package com.lihua.newideas.config;


import com.lihua.newideas.handler.MyAccessDeniedHandler;
import com.lihua.newideas.handler.MyAuthenticationFailureHandler;
import com.lihua.newideas.handler.MyAuthenticationSuccessHandler;
import com.lihua.newideas.service.impl.MyUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAccessDeniedHandler deniedHandler;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    @Autowired
    private MyUserDetailsServiceImpl userDetailsService;
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        ///首页所有人可以访问，功能页只有对应有权限的人才能访问
        //请求授权规则
        http.authorizeRequests()
                .antMatchers("/").permitAll() //”/"页面所有人都能访问
                .antMatchers("/toLogin").permitAll()
                .antMatchers("/toError").permitAll()
                .antMatchers("/articleDetails").permitAll()

                .antMatchers("/css/**","/js/**","/image/**","/plugins/**").permitAll()//放行静态资源

                //除了放行的请求，其他都需要认证
                .antMatchers("/test").hasAuthority("not") //任何人都不能访问


                //权限设置
                .antMatchers("/admin/**","/uploadFile","/goUploadView").hasAuthority("admin") //赋予单个权限
//                .antMatchers("/authority/admin").hasAnyAuthority("admin","normal")//赋予多个权限


                //赋予角色
//                .antMatchers("/level1/**").hasAnyRole("vip2","vip1","vip3")//"/level1/**"页面只有被赋予vip1角色的用户能访问
//                .antMatchers("/level2/**").hasAnyRole("vip2","vip3")//"/level2/**"页面只有被赋予vip2角色的用户能访问
                .antMatchers("/level3/**").hasRole("vip3");//"/level1/**"页面只有被赋予vip1角色的用户能访问

//                //基于ip赋予权限
//                .antMatchers("/level1/**").hasIpAddress("127.0.0.1")

//                .anyRequest().authenticated(); //没有授权的页面,如果没有登录则没有权限访问

        //没有权限会跳到登录界面,这句代码就是开启登录页面的,loginPage("/toLogin")使用自己的登陆页面
        http.formLogin()
                .loginPage("/toLogin")  //定制登录页面
//                .successForwardUrl("/") //登录成功跳转界面
//                .successHandler(new MyAuthenticationSuccessHandler("https://www.baidu.com/")) //定制登录成功(处理器)重定向界面,适用于前后端分离
                .successHandler(new MyAuthenticationSuccessHandler("/")) //登录成功后跳转的页面
//                .failureForwardUrl("/toError")//登录失败跳转界面
                .failureHandler(new MyAuthenticationFailureHandler("/toError")) //自定义失败处理器
                .passwordParameter("pass") //设置前端表单的name属性的值
                .usernameParameter("user").loginProcessingUrl("/login");//更改登录的页面点击提交后的action的路径


        //记住我
        http.rememberMe()
                .tokenRepository(persistentTokenRepository)
                .rememberMeParameter("rememberMe")
                //超时时间
//                .tokenValiditySeconds(60) //如果不配置默认两周
                .userDetailsService(userDetailsService);//自定义登录逻辑  //注意这个必须写

////        .logout().deleteCookies(&quot;remove&quot;).invalidateHttpSession(false)  是否删除cookie和session
//
        http.logout().logoutSuccessUrl("/");
//        //  注销报错404的话，需要加这个代码
//        //防止网站工具：get，post。这个是安全工具。不知道啥原理

//403页面定制(无权限访问的页面更改)
        http.exceptionHandling().accessDeniedHandler(deniedHandler);

        //
        http.csrf().disable();//关闭csrf功能
        http.headers().frameOptions().disable();  //关闭这个不然无法使用layui弹窗组件

    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        //设置数据源
        jdbcTokenRepository.setDataSource(dataSource);
        //自动建表,第一次自动建表,第二次启动记得注释掉,不然会报错
//        jdbcTokenRepository.setCreateTableOnStartup(true);

        return jdbcTokenRepository;

    }
}
